/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package wave;

import ast.*;
import base.*;
import java.util.Hashtable;
import java.util.StringTokenizer;
import java.util.Vector;
import trackmsg.EchoMsg;
import trackmsg.TrackCtrlMsg;

/**
 *
 * @author FUJISAI
 */
public class ASTSumExecution extends WaveExecution {
    public ASTSumExecution(WaveHeadParser parser, WaveEnvironment waveEnv) {
        super(parser, waveEnv);
    }

    public void execute(ASTSum sum, String tail) {
        
        SimpleNode left = (SimpleNode)sum.jjtGetChild(0);
        SimpleNode right = (SimpleNode)sum.jjtGetChild(1);

        Hashtable<String, Vector> fTab = this.waveEnv.getFrontalTable();
        Vector right_value = getASTNodeValue(right);
        if (left instanceof ASTFrontalVar) {
            
            Vector v_left = fTab.get(left.getString());

            if (v_left == null) {
                v_left = new Vector();
                //fTab.put(left.getString(), v_left);
            }
            Utilities.WPPrint("V_LEFT: " + v_left);
            fTab.put(left.getString(), WaveActs.add(v_left, right_value));
        }

        else if (left instanceof ASTNodalVar) {
            Hashtable nTab = this.kn.getKNNode(this.waveEnv.getCONTENT()).
                    getNodalTable(waveEnv.getColor());
            Vector v_left = (Vector)nTab.get(left.getString());

            if (v_left == null) {
                v_left = new Vector();
                nTab.put(left.getString(), v_left);
            }

            if (right instanceof ASTFrontalVar) {
                Vector v_right = (Vector)fTab.get(right.getString());

                nTab.put(left.getString(), WaveActs.add(v_left, v_right));
                Utilities.WPPrint(nTab);
            }
            else if (right instanceof ASTNodalVar) {
                Vector v_right = (Vector)nTab.get(right.getString());

                nTab.put(left.getString(), WaveActs.add(v_left, v_right));
                Utilities.WPPrint(nTab);
            }
            else if (right instanceof ASTNone) {
                Utilities.WPPrint(nTab);
            }
            else if (right instanceof ASTTraveledLink) {
                Vector link = new Vector();
                String temp = this.waveEnv.getLINK();

                if (temp.charAt(0) == '`' && temp.charAt(temp.length()-1) == '\'' ) {
                    temp = temp.substring(1, temp.length()-1);
                }

                if (isNum(temp) == true)
                    link.add(Integer.parseInt(temp));
                else
                    link.add(temp);

                nTab.put(left.getString(), WaveActs.add(v_left, link));
            }
            else {
                StringTokenizer strTk = new StringTokenizer(right.getString());
                Vector v_right = new Vector();
                while (strTk.hasMoreTokens()) {
                    String temp = strTk.nextToken(";");
                    if (isNum(temp) == true)
                        v_right.add(Integer.parseInt(temp));
                    else
                        v_right.add(temp);
                }

                nTab.put(left.getString(), WaveActs.add(v_left, v_right));
            }
        }
        
        if (waveEnv.getTrackAddress() != null) {
            //TrackNode duoc chua trong trackForest
            //lay ra track node tu address trong waveEnv
            TrackNode fromTrack = wi.getTrackForest().getTrackNode(waveEnv.getTrackAddress());
            TrackNode.Echo echo = TrackNode.Echo.TRUE;
            //Neu tail ma rong thi gui echo la TRUE di
            if(tail.equals("")){
                //Tao message echo va gui vao TrackQueue
                TrackCtrlMsg msg = new EchoMsg(fromTrack, echo, waveEnv);
                wi.getTrackQueue().incoming(msg);
            } else {
                Wave newWave = new Wave(tail, new WaveEnvironment(waveEnv));
                waveQueue.incomingFront(newWave);               
            }
        } else if ( !tail.trim().equals("") ) {
            Wave newWave = new Wave(tail, new WaveEnvironment(waveEnv));
            waveQueue.incomingFront(newWave);
        }
        waveEnv.dump();
        Utilities.WPPrint("Executed Done!");
    }

    public boolean isNum (String str) {
        try{
            Integer.parseInt(str);
        } catch(NumberFormatException nfe) {
            return false;
        }
        return true;
    }
}
